/**
 @file sys_usw_flexe.h

 @author  Copyright (C) 2011 Centec Networks Inc.  All rights reserved.

 @date 2011-11-9

 @version v2.0

*/

#ifndef _SYS_USW_FLEXE_H
#define _SYS_USW_FLEXE_H
#ifdef __cplusplus
extern "C" {
#endif

/****************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sal.h"

#include "ctc_const.h"
#include "ctc_port.h"
#include "ctc_interrupt.h"
#include "ctc_flexe.h"


/****************************************************************
*
* Defines and Macros
*
****************************************************************/
#define SYS_FLEXE_INIT_CHECK()            \
    do                                   \
    {                                    \
        LCHIP_CHECK(lchip); \
        if (NULL == p_usw_flexe_master[lchip]){      \
            return CTC_E_NOT_INIT; }     \
    }                                    \
    while (0)

#define SYS_FLEXE_DBG_OUT(level, FMT, ...) \
    do { \
        CTC_DEBUG_OUT(flexe, flexe, FLEXE_SYS, level, FMT, ##__VA_ARGS__); \
    } while (0)


#define SYS_FLEXE_CR_TIMER_POLLING_CLK           100

struct sys_flexe_cr_timer_s
{
    uint8  inst_bmp;
    uint32 clk_cnt;
    uint32 group_id;
};
typedef struct sys_flexe_cr_timer_s sys_flexe_cr_timer_t;

struct sys_flexe_monitor_task_s
{
    sal_task_t* monitor_task;
    uint8 task_end;
};
typedef struct sys_flexe_monitor_task_s sys_flexe_monitor_task_t;

struct sys_flexe_master_s
{
    sal_task_t*            p_monitor_scan;
    sal_task_t*            p_monitor_alarm_scan;    
    uint8                  polling_status;

    ctc_slist_t*           group_list;
    ctc_slist_t*           client_list;
    
    sys_flexe_cr_timer_t**   cr_timer;
    sys_flexe_monitor_task_t cr_timer_scan;
};
typedef struct sys_flexe_master_s sys_flexe_master_t;

extern sys_flexe_master_t* p_usw_flexe_master[CTC_MAX_LOCAL_CHIP_NUM_PP];


/* OIF spec */
#define SYS_FLEXE_MAX_GROUP_NUM          0xffffe
#define SYS_FLEXE_MAX_CLIENT_NUM          0xfffe
#define SYS_FLEXE_MAX_PHY_NUMBER             128
#define SYS_FLEXE_SLOT_SPEED                   5
#define SYS_FLEXE_CLIENT_NUM_BLOCKS            8
#define SYS_FLEXE_OHRAM_BLKNUM                16
#define SYS_FLEXE_OH_FRAME_NUM_50G            16
#define SYS_FLEXE_OH_FRAME_NUM                32
#define SYS_FLEXE_OH_MAX_HALFBLK_FLD           4
#define SYS_FLEXE_MAX_PHY_NUM(phy_speed)     \
    (CTC_PORT_SPEED_100G == phy_speed) ? 254 : ((CTC_PORT_SPEED_400G == phy_speed) ? 62 : 126)



/* ALARM */
#define SYS_FLEXE_EVENT_CLIENT_MISMATCH       16  /**< FlexE CCM event, alarm by client, is related to ctc_flexe_event_type_t */



/* SDK */
#define SYS_SET_BIT_CHECK(val_32, bit_mask)        (bit_mask == (val_32 & bit_mask))

#define SYS_FLEXE_ACTIVE_A                     0
#define SYS_FLEXE_ACTIVE_B                     1

#define SYS_FLEXE_UNUSED_FLAG_U8            0xff
#define SYS_FLEXE_UNUSED_FLAG_U16         0xffff
#define SYS_FLEXE_UNUSED_FLAG_U32     0xffffffff

#define SYS_FLEXE_USED_FLAG_U32_LOW_2         0xfffffffc

#define SYS_FLEXE_UNSUPP                    0xff

#define SYS_FLEXE_CFG_FLAG                     2
#define SYS_FLEXE_ACTIVE_FLAG                  1
#define SYS_FLEXE_INACTIVE_FLAG                0


#define SYS_FLEXE_MODE_2_LANE_NUM(mode, lane_num)    \
{                                                    \
    switch (mode)                                    \
    {                                                \
    case CTC_CHIP_SERDES_CDG_R8_MODE:                \
        lane_num = 8;                                \
        break;                                       \
    case CTC_CHIP_SERDES_CCG_R4_MODE:                \
    case CTC_CHIP_SERDES_CG_MODE:                    \
        lane_num = 4;                                \
        break;                                       \
    case CTC_CHIP_SERDES_CG_R2_MODE:                 \
    case CTC_CHIP_SERDES_LG_MODE:                    \
        lane_num = 2;                                \
        break;                                       \
    case CTC_CHIP_SERDES_LG_R1_MODE:                 \
        lane_num = 1;                                \
        break;                                       \
    default:                                         \
        lane_num = 0;                                \
        break;                                       \
    }                                                \
}

#define SYS_FLEXE_MODE_2_SPEED(mode, speed)  \
{                                            \
	switch (mode)                            \
	{                                        \
	case CTC_CHIP_SERDES_LG_MODE:            \
	case CTC_CHIP_SERDES_LG_R1_MODE:         \
	    speed = CTC_PORT_SPEED_50G;          \
	    break;                               \
	case CTC_CHIP_SERDES_CG_MODE:            \
	case CTC_CHIP_SERDES_CG_R2_MODE:         \
	    speed = CTC_PORT_SPEED_100G;         \
	    break;                               \
	case CTC_CHIP_SERDES_CCG_R4_MODE:        \
	    speed = CTC_PORT_SPEED_200G;         \
	    break;                               \
	case CTC_CHIP_SERDES_CDG_R8_MODE:        \
	    speed = CTC_PORT_SPEED_400G;         \
	    break;                               \
    default:                                 \
	    speed = CTC_PORT_SPEED_MAX;          \
	    break;                               \
	}                                        \
}

#define SYS_FLEXE_SPEED_2_VAL(speed, val)  \
{                                          \
    switch (speed)                         \
    {                                      \
    case CTC_PORT_SPEED_50G:               \
        val = 50;                          \
        break;                             \
    case CTC_PORT_SPEED_100G:              \
        val = 100;                         \
        break;                             \
    case CTC_PORT_SPEED_200G:              \
        val = 200;                         \
        break;                             \
    case CTC_PORT_SPEED_400G:              \
        val = 400;                         \
        break;                             \
    default:                               \
        val = 0;                           \
        break;                             \
    }                                      \
}

#define SYS_FLEXE_SPEED_VAL_2_MODE(val, mode)                                  \
{                                                                               \
    if ((val) > 200)                           (mode) = CTC_PORT_SPEED_400G;    \
    else if (((val) > 100) && ((val) <= 200))  (mode) = CTC_PORT_SPEED_200G;    \
    else if (((val) > 50) && ((val) <= 100))   (mode) = CTC_PORT_SPEED_100G;    \
    else if (((val) > 40) && ((val) <= 50))    (mode) = CTC_PORT_SPEED_50G;     \
    else if (((val) > 25) && ((val) <= 40))    (mode) = CTC_PORT_SPEED_40G;     \
    else if (((val) > 20) && ((val) <= 25))    (mode) = CTC_PORT_SPEED_25G;     \
    else if (((val) > 10) && ((val) <= 20))    (mode) = CTC_PORT_SPEED_20G;     \
    else if (((val) > 5) && ((val) <= 10))     (mode) = CTC_PORT_SPEED_10G;     \
    else if (((val) > 0) && ((val) <= 5))      (mode) = CTC_PORT_SPEED_5G;      \
    else                                       (mode) = CTC_PORT_SPEED_MAX;     \
}

enum sys_flexe_check_val_type_e
{
    SYS_FLEXE_CHECK_GROUP_NUM,
    SYS_FLEXE_CHECK_PHY_NUM,
    SYS_FLEXE_CHECK_CLIENT_NUM,
    SYS_FLEXE_CHECK_BINARY,
    
    SYS_FLEXE_CHECK_VAL_MAX
};
typedef enum sys_flexe_check_val_type_e sys_flexe_check_val_type_t;

enum sys_flexe_dir_e
{
    SYS_FLEXE_DIR_RX,
    SYS_FLEXE_DIR_TX,
     
    SYS_FLEXE_DIR_MAX
};
typedef enum sys_flexe_dir_e sys_flexe_dir_t;

enum sys_flexe_intr_tbl_type_e
{
    SYS_FLEXE_INTR_BMP_IDX,
    SYS_FLEXE_INTR_INST,
    SYS_FLEXE_INTR_VALUE,
    SYS_FLEXE_INTR_MASK,

    SYS_FLEXE_INTR_BIT_BUTT
};
typedef enum sys_flexe_intr_tbl_type_e sys_flexe_intr_tbl_type_t;

enum sys_flexe_oh_flip_type_e
{
    SYS_FLEXE_OH_FLIP_FALLING = 0,
    SYS_FLEXE_OH_FLIP_RISING  = 1,
    SYS_FLEXE_OH_FLIP_NONE,

    SYS_FLEXE_OH_FLIP_MAX
};
typedef enum sys_flexe_oh_flip_type_e sys_flexe_oh_flip_type_t;

enum sys_flexe_oh_field_e
{
    FLEXE_OH_FIELD_C_0       = 0,
    FLEXE_OH_FIELD_C_1       = 1,
    FLEXE_OH_FIELD_C_2       = 2,
    FLEXE_OH_FIELD_OMF       = 3,
    FLEXE_OH_FIELD_RPF       = 4,
    FLEXE_OH_FIELD_SC        = 5,
    FLEXE_OH_FIELD_GRP_NUM   = 6,
    FLEXE_OH_FIELD_MAP       = 7,
    FLEXE_OH_FIELD_INST_NUM  = 8,
    FLEXE_OH_FIELD_CAL_A     = 9,
    FLEXE_OH_FIELD_CAL_B     = 10,
    FLEXE_OH_FIELD_CAL_B_15  = 11,
    FLEXE_OH_FIELD_CR        = 12,
    FLEXE_OH_FIELD_CA        = 13,

    FLEXE_OH_FIELD_MAX
};
typedef enum sys_flexe_oh_field_e sys_flexe_oh_field_t;

enum sys_flexe_oh_field_type_e
{
    /*
      FLEXE_OH_FIELD_GRP_NUM   = 6,
     */
    FLEXE_OH_FIELD_TYPE_GROUP_NUM,
    /*
      FLEXE_OH_FIELD_MAP       = 7,
     */
    FLEXE_OH_FIELD_TYPE_FLEXE_MAP,
    /*
      FLEXE_OH_FIELD_INST_NUM  = 8,
     */
    FLEXE_OH_FIELD_TYPE_INST_NUM,

    /*
      FLEXE_OH_FIELD_CAL_A     = 9,
      FLEXE_OH_FIELD_CAL_B     = 10,
      FLEXE_OH_FIELD_CAL_B_15  = 11,
     */
    FLEXE_OH_FIELD_TYPE_CLIENT_CAL,

    /*
      FLEXE_OH_FIELD_CR        = 12,
     */
    FLEXE_OH_FIELD_TYPE_CR,

    /*
      FLEXE_OH_FIELD_CA        = 13,
     */
    FLEXE_OH_FIELD_TYPE_CA,

    /*
      FLEXE_OH_FIELD_C_0       = 0,
      FLEXE_OH_FIELD_C_1       = 1,
      FLEXE_OH_FIELD_C_2       = 2,
     */
    FLEXE_OH_FIELD_TYPE_C_BIT,

    /*
      FLEXE_OH_FIELD_CR        = 12,
      FLEXE_OH_FIELD_C_0       = 0,
      FLEXE_OH_FIELD_C_1       = 1,
      FLEXE_OH_FIELD_C_2       = 2,
     */
    FLEXE_OH_FIELD_TYPE_CR_C,

    /*
      FLEXE_OH_FIELD_SC        = 5,
     */
    FLEXE_OH_FIELD_TYPE_SC,

    /*
      FLEXE_OH_FIELD_CAL_A     = 9,
     */
    FLEXE_OH_FIELD_TYPE_CLIENT_CAL_A,

    /*
      FLEXE_OH_FIELD_CAL_B     = 10,
      FLEXE_OH_FIELD_CAL_B_15  = 11,
     */
    FLEXE_OH_FIELD_TYPE_CLIENT_CAL_B,

    FLEXE_OH_FIELD_TYPE_MAX
};
typedef enum sys_flexe_oh_field_type_e sys_flexe_oh_field_type_t;

enum sys_flexe_oh_info_e
{
    FLEXE_OH_INFO_VALID_FLAG,
    FLEXE_OH_INFO_HALF_BLK_ID,
    FLEXE_OH_INFO_START_BIT,
    FLEXE_OH_INFO_MASK,
    FLEXE_OH_INFO_ALL
};
typedef enum sys_flexe_oh_info_e sys_flexe_oh_info_t;

struct sys_flexe_oh_halfblk_fld_s
{
    uint8 halfblk_id;
    uint8 field_num;
    uint8 field[SYS_FLEXE_OH_MAX_HALFBLK_FLD];
};
typedef struct sys_flexe_oh_halfblk_fld_s sys_flexe_oh_halfblk_fld_t;

enum sys_flexe_group_crac_state_e
{
    SYS_FLEXE_GROUP_TX_IDLE,
    SYS_FLEXE_GROUP_TX_CR_SENT,
    SYS_FLEXE_GROUP_TX_CA_RCV,
    SYS_FLEXE_GROUP_TX_C_SENT,

    SYS_FLEXE_GROUP_RX_IDLE,
    SYS_FLEXE_GROUP_RX_CR_RCV,
    SYS_FLEXE_GROUP_RX_CA_SENT,
    SYS_FLEXE_GROUP_RX_C_RCV,

    SYS_FLEXE_GROUP_MAX_STATE
};
typedef enum sys_flexe_group_crac_state_e sys_flexe_group_crac_state_t;

enum sys_flexe_client_prop_e
{
    SYS_FLEXE_CLIENT_PROP_HW_CLIENT = CTC_FLEXE_CLIENT_PROP_MAX,
    SYS_FLEXE_CLIENT_PROP_BIND_OAM,
    SYS_FLEXE_CLIENT_PROP_MAX
};
typedef enum sys_flexe_client_prop_e  sys_flexe_client_prop_t;

enum sys_flexe_slot_state_e
{
    SYS_FLEXE_SLOT_FIX,
    SYS_FLEXE_SLOT_ADD,
    SYS_FLEXE_SLOT_REMOVE,
    
    SYS_FLEXE_SLOT_MAX
};
typedef enum sys_flexe_client_prop_e  sys_flexe_slot_state_t;

enum sys_flexe_client_state_e
{
    SYS_FLEXE_CLIENT_ADD,
    SYS_FLEXE_CLIENT_REMOVE,
    SYS_FLEXE_CLIENT_RESIZE,

    SYS_FLEXE_CLIENT_MAX
};
typedef enum sys_flexe_client_prop_e  sys_flexe_client_state_t;

enum sys_flexe_event_action_e
{
    SYS_FLEXE_EVENT_NONE,
    SYS_FLEXE_EVENT_SET,
    SYS_FLEXE_EVENT_CLEAR,
    
    SYS_FLEXE_EVENT_MAX
};
typedef enum sys_flexe_event_action_e sys_flexe_event_action_t;

struct sys_flexe_client_chg_s
{
    uint32 id;
    uint32 gport;
    uint32 speed;
};
typedef struct sys_flexe_client_chg_s sys_flexe_client_chg_t;

/* Current Using Spec */
#define SYS_FLEXE_MAX_OH_PHY_INST_CNT      4
#define SYS_FLEXE_MAX_INST_CNT             8
#define SYS_FLEXE_MAX_SLOT_PER_INST        10
#define SYS_FLEXE_MAX_CYCLE                80 
#define SYS_FLEXE_MAX_CLIENT               60
#define SYS_FLEXE_GROUP_MAX_PHY_CNT        8


/* OIF Spec */
#define SYS_FLEXE_OH_MAX_SLOT_PER_INST     20
#define SYS_FLEXE_INSTANCE_SLOT_50G_NUM    10
#define SYS_FLEXE_INSTANCE_SLOT_100G_NUM   20
#define SYS_FLEXE_INSTANCE_SLOT_200G_NUM   40
#define SYS_FLEXE_INSTANCE_SLOT_400G_NUM   80

enum sys_flexe_switch_mode_e
{
    SYS_FLEXE_DYNAMIC_NEGO_SWITCH = 0,   /* dynamic negotiation switch */
    SYS_FLEXE_STATIC_SWITCH       = 1,   /* static switch */

    SYS_FLEXE_SWITCH_MODE_MAX
};
typedef enum sys_flexe_switch_mode_e sys_flexe_switch_mode_t;

enum sys_flexe_rx_mode_e
{
    SYS_FLEXE_RX_LOCAL_CONFIGURATION = 0,   /* rx local configuration */
    SYS_FLEXE_RX_F0LLOW_REMOTE       = 1,   /* rx follow remote */

    SYS_FLEXE_RX_MODE_MAX
};
typedef enum sys_flexe_rx_mode_e sys_flexe_rx_mode_t;

enum sys_flexe_client_flow_e
{
    SYS_FLEXE_FLOW_TYPE_A = 0,
    SYS_FLEXE_FLOW_TYPE_B = 1,
    SYS_FLEXE_FLOW_TYPE_C = 2,
    SYS_FLEXE_FLOW_MAX    = 3
};
typedef enum sys_flexe_client_flow_e sys_flexe_client_flow_t;

enum sys_flexe_alloc_ret_e
{
    SYS_FLEXE_ALLOC_SUCCESS,
    SYS_FLEXE_ALLOC_RET_NO_MAC,
    SYS_FLEXE_ALLOC_RET_NO_CREDIT,
    SYS_FLEXE_ALLOC_RET_NO_CHAN,

    SYS_TMM_FLEXE_ALLOC_MAX_TYPE
};
typedef enum sys_flexe_alloc_ret_e sys_flexe_alloc_ret_t;

enum sys_flexe_phy_status_type_e
{
    SYS_FLEXE_PCS_LINK,
    SYS_FLEXE_OH_LOCK,
    SYS_FLEXE_OHMF_LOCK,
    SYS_FLEXE_PAD_LOCK,
    SYS_FLEXE_RPF_CLEAR,

    SYS_FLEXE_LOCK_MAX_TYPE
};
typedef enum sys_flexe_phy_status_type_e sys_flexe_phy_status_type_t;

struct sys_flexe_inst_state_s
{
    uint32 inst_offset; /* key */
    uint32 event_bmp; /* ctc_flexe_event_type_t */
    uint32 group_num;
    uint32 instance_num;
    
    uint8  flexe_map[SYS_FLEXE_OH_FRAME_NUM];
    uint8  rsv0[3];

    uint32 client_map[SYS_FLEXE_OH_MAX_SLOT_PER_INST];
    uint32 client_map_b[SYS_FLEXE_OH_MAX_SLOT_PER_INST];
};
typedef struct sys_flexe_inst_state_s sys_flexe_inst_state_t;

struct sys_flexe_phy_s
{
    uint32                       phy_number;

    uint8                        logical_serdes_base;  /* the first logical serdes for the PHY */
    uint8                        inst_base;
    uint8                        pcs_mode;    /* ctc_chip_serdes_mode_t */
    uint8                        fec_type;    /* ctc_port_fec_type_t */
    uint8                        rsv;

    uint32                       crc_cnt;
    uint32                       event_bmp;
    sys_flexe_inst_state_t       remote_state[SYS_FLEXE_MAX_OH_PHY_INST_CNT];
};
typedef struct sys_flexe_phy_s sys_flexe_phy_t;

struct sys_flexe_inst_s
{
    uint8   slot_cfg_shim_chid[SYS_FLEXE_MAX_SLOT_PER_INST];
    uint8   rsv0[2];
    uint8   switch_shim_chid_a[SYS_FLEXE_MAX_SLOT_PER_INST];
    uint8   rsv1[2];
    uint8   switch_shim_chid_b[SYS_FLEXE_MAX_SLOT_PER_INST];
    uint8   rsv2[2];

    uint16  flush_bmp;        /* carry SYS_FLEXE_MAX_SLOT_PER_INST slots */
    
    uint8   crcac_intr_bmp;   /* bit[1:0] - cr
                                 bit[3:2] - ca
                                 bit[5:4] - c
                                 value 0: no intr; 1 - falling; 2 - rising
                                 only used for RX
                               */
    uint8   cr_flip       :2;  /* refer to sys_flexe_oh_flip_type_t; only used for RX */
    uint8   ca_flip       :2;  /* refer to sys_flexe_oh_flip_type_t; only used for RX */
    uint8   c_flip        :2;  /* refer to sys_flexe_oh_flip_type_t; only used for RX */
    uint8   rsv_bit       :2;  /* refer to sys_flexe_oh_flip_type_t; only used for RX */
    
    uint8   rsv3;
};
typedef struct sys_flexe_inst_s sys_flexe_dir_inst_t;


struct sys_flexe_cc_inst_s
{
    uint8 slot_cnt;
    uint8 slot_list[SYS_FLEXE_MAX_SLOT_PER_INST];
    uint8 cc_subcalmask;   /* carry 8*66bit block */
};
typedef struct sys_flexe_cc_inst_s sys_flexe_cc_inst_t;

struct sys_flexe_group_cc_s
{
    uint8                   cycle_value;
    uint8                   shim_chid;
    sys_flexe_cc_inst_t*    inst;
};
typedef struct sys_flexe_group_cc_s sys_flexe_group_cc_t;

struct sys_flexe_group_ic_s
{
    uint8  shim_chid;
    uint16 ic_subcalmask;   /* carry SYS_FLEXE_MAX_SLOT_PER_INST slots */
};
typedef struct sys_flexe_group_ic_s sys_flexe_group_ic_t;

struct sys_flexe_group_dir_s
{
    uint8                             active;      /* SYS_FLEXE_ACTIVE_A / SYS_FLEXE_ACTIVE_B */
    uint8                             crac_state;  /* sys_flexe_group_crac_state_t */
    sys_flexe_dir_inst_t*             dir_inst;
    /* client cycle scheduler */
    sys_flexe_group_cc_t          cc[SYS_FLEXE_MAX_CYCLE];
    /* instance cycle scheduler */
    sys_flexe_group_ic_t          ic[SYS_FLEXE_MAX_INST_CNT][SYS_FLEXE_MAX_CYCLE];
};
typedef struct sys_flexe_group_dir_s sys_flexe_group_dir_t;

struct sys_flexe_group_s
{
    ctc_slistnode_t           head;

    uint32                    group_id;
    uint32                    group_number;
    uint8                     switch_mode;     /* sys_flexe_switch_mode_t */
    uint8                     rx_cfg_mode;     /* ctc_flexe_group_rx_mode_t */
    uint8                     flexe_shim_id;
    uint8                     inst_cnt;
    uint8                     phy_cnt;
    uint8                     pad_en;    /* FlexE group PHY pad enable/disable, only for lg(R1) and lg(R2) */
    uint8                     rsv[2];
    uint32                    event_bmp;
    sys_flexe_phy_t*          phy_list;
    uint8*                    inst_list;

    sys_flexe_group_dir_t tx;
    sys_flexe_group_dir_t rx;
    uint32                    cr_timer;
};
typedef struct sys_flexe_group_s sys_flexe_group_t;

struct sys_flexe_client_dir_s
{
    uint8 op;   /* sys_flexe_client_state_t */
    uint8 read_ptr;
    uint8 rsv[2];
};
typedef struct sys_flexe_client_dir_s sys_flexe_client_dir_t;

struct sys_flexe_client_s
{
    ctc_slistnode_t             head;

    uint32                      client_id;
    uint32                      client_number;
    uint32                      group_id;

    uint8                       flexe_shim_id;
    uint8                       shim_chid;
    uint8                       tx_xc_chid;
    uint8                       rx_xc_chid;

    uint32                      cross_client_id;
    uint32                      gport;

    uint16                      mac_id;
    uint8                       chan_id;
    uint8                       cross_enable    :1;
    uint8                       aps_role        :2;  /*0:no aps, 1:aps working path, 2:aps protect path*/
    uint8                       bind_oam        :1;  /*0:no bind oam, 1:bind oam*/
    uint8                       rsv             :4;

    uint8                       flow_type;
    uint8                       rsv1[3];

    uint32                      event_bmp;

    sys_flexe_client_dir_t  tx;
    sys_flexe_client_dir_t  rx;
};
typedef struct sys_flexe_client_s sys_flexe_client_t;

struct sys_flexe_slot_s
{
    uint8 change;   // 0-fix, 1-add, 2-remove, 3-none
    uint8 shim_chid_old;
    uint8 shim_chid_new;
};
typedef struct sys_flexe_slot_s sys_flexe_slot_t;

struct sys_flexe_slot_change_s
{
    sys_flexe_slot_t slot[SYS_FLEXE_INSTANCE_SLOT_400G_NUM];  ///TODO: optimize structure
};
typedef struct sys_flexe_slot_change_s sys_flexe_slot_change_t;

struct sys_flexe_client_calgen_s
{
    uint8 sch_cnt;
    uint8 sel;
    uint8 pending;
    int32 cur_interval;
    int32 init_interval;
    uint8 sch_total_cnt;
    uint8 sch_sel_cnt;
    uint8 rm_flag;
    uint8 sch_cnt_max;
    uint32 speed;
};
typedef struct sys_flexe_client_calgen_s sys_flexe_client_calgen_t;

struct sys_flexe_client_calcfg_s
{
    uint8  xc_chid;
    uint8  rx_xc_chid;
    uint32 speed;
    uint16 mac_id;   /* global */
    sys_flexe_client_flow_t flow_type;
};
typedef struct sys_flexe_client_calcfg_s sys_flexe_client_calcfg_t;

enum sys_flexe_mgr_intr_type_e
{
    SYS_FLEXE_MGR_INTR_OHLOCK,
    SYS_FLEXE_MGR_INTR_OHLOCKLOS,
    SYS_FLEXE_MGR_INTR_OHMFLOCK,
    SYS_FLEXE_MGR_INTR_OHMFLOCKLOS,
    SYS_FLEXE_MGR_INTR_CR,
    SYS_FLEXE_MGR_INTR_CA,
    SYS_FLEXE_MGR_INTR_C,
    SYS_FLEXE_MGR_INTR_RPF_FALLING,
    SYS_FLEXE_MGR_INTR_RPF_RISING,

    SYS_FLEXE_MGR_INTR_MAX_TYPE
};
typedef enum sys_flexe_mgr_intr_type_e sys_flexe_mgr_intr_type_t;

struct sys_flexe_mgr_intr_s
{
    uint8 inst;
    uint8 word_no;
    uint8 bit;
    sys_flexe_mgr_intr_type_t intr_type;
};
typedef struct sys_flexe_mgr_intr_s sys_flexe_mgr_intr_t;

struct sys_flexe_oh_rx_info_s
{
    uint32 sc;
    uint32 group_num;
    uint32 inst_num;
    uint8  rpf;
    uint8  cr;
    uint8  ca;
    uint8  c0;
    uint8  c1;
    uint8  c2;
    uint32 flexe_map_cnt;
    uint32 flexe_map[CTC_FLEXE_OH_MF_NUM];
    uint32 inst_client_map[SYS_FLEXE_MAX_INST_CNT][SYS_FLEXE_OH_MAX_SLOT_PER_INST];
    uint32 inst_client_map_b[SYS_FLEXE_MAX_INST_CNT][SYS_FLEXE_OH_MAX_SLOT_PER_INST];
};
typedef struct sys_flexe_oh_rx_info_s sys_flexe_ohram_info_t;

/**********************Anchor_Point******************************************************************************************/



/****************************************************************************
 *
* Function
*
*****************************************************************************/

extern int32
sys_usw_flexe_set_en(uint8 lchip, uint16 serdes_id, uint8 enable);
extern int32
sys_usw_flexe_get_en(uint8 lchip, uint16 serdes_id, uint8* enable);
extern int32
sys_usw_flexe_create_group(uint8 lchip, uint32 group_id, ctc_flexe_grp_t* p_group);
extern  int32
sys_usw_flexe_destroy_group(uint8 lchip, uint32 group_id);
extern int32
sys_usw_flexe_get_group(uint8 lchip, uint32 group_id, ctc_flexe_grp_t* p_group);
extern int32
sys_usw_flexe_set_group_property(uint8 lchip, uint32 group_id, ctc_flexe_grp_prop_t group_prop, void* p_value);
extern int32
sys_usw_flexe_get_group_property(uint8 lchip, uint32 group_id, ctc_flexe_grp_prop_t group_prop, void* p_value);
extern int32
sys_usw_flexe_add_client(uint8 lchip, uint32  client_id, ctc_flexe_client_t* p_client);
extern int32
sys_usw_flexe_remove_client(uint8 lchip, uint32  client_id);
extern int32
sys_usw_flexe_get_client(uint8 lchip, uint32  client_id, ctc_flexe_client_t* p_client);
extern int32
sys_usw_flexe_set_client_property(uint8 lchip, uint32  client_id, ctc_flexe_client_prop_t client_prop, void* p_value);
extern int32
sys_usw_flexe_get_client_property(uint8 lchip, uint32  client_id, ctc_flexe_client_prop_t client_prop, void* p_value);
extern int32
sys_usw_flexe_get_client_link_up(uint8 lchip, uint32  client_id, bool* p_is_up);
extern int32
sys_usw_flexe_set_client_cross(uint8 lchip, ctc_flexe_cross_t* p_cross);
extern int32
sys_usw_flexe_get_client_cross(uint8 lchip, ctc_flexe_cross_t* p_cross);
extern int32
sys_usw_flexe_set_phy_property(uint8 lchip, uint16 serdes_id, ctc_flexe_phy_prop_t phy_prop, void* p_value);
extern int32
sys_usw_flexe_get_phy_property(uint8 lchip, uint16 serdes_id, ctc_flexe_phy_prop_t phy_prop, void* p_value);
extern int32
sys_usw_flexe_get_phy_inst_id(uint8 lchip, uint8 dp_id, uint8 asic_inst_id, uint8* p_serdes_id, uint32* p_instance_id);
extern int32
sys_usw_flexe_get_phy_oh_sync(uint8 lchip, uint8 serdes_id, uint32* p_enable);
extern int32
sys_usw_flexe_get_dp_asic_id(uint8 lchip, uint8 serdes_id, uint32 instance_id, uint8* p_dp_id, uint8 p_asic_inst_id[]);

extern int32
sys_usw_flexe_init(uint8 lchip, void* p_cfg);
extern int32
sys_usw_flexe_deinit(uint8 lchip);

#ifdef __cplusplus
}
#endif

#endif
